

import 'dart:async';
import 'dart:io';

import 'package:bike_ride/common/util/extension.dart';
import 'package:bike_ride/common/widget/dialog/mydialog.dart';
import 'package:bike_ride/generated/l10n.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:geolocator/geolocator.dart';
import 'package:permission_handler/permission_handler.dart';

typedef CallBack = Function(bool success, String msg);


class PermissionUtil{
  static final cameraPermissions = {S.current.cameraPermission:Permission.camera};

  Future<PermissionStatus> handleNotificationPermission()async{
    return await Permission.notification.request();
  }


  static handleCameraPermission(BuildContext context,CallBack callBack)async{
    if(await Permission.camera.status != PermissionStatus.granted){
      if(context.mounted){
        showCameraPermissionDialog(context, centralControlBol:true,onSuccess: ()async{
          requestPermissions(context,cameraPermissions,callBack);
        });
      }
    }else{
      callBack(true,S.current.finishGrandPer);
    }
  }


  ///蓝牙功能需要同时请求 定位、蓝牙权限
  static final bluePermissions = Platform.isIOS?{S.current.bluePermission:Permission.bluetooth}:{S.current.searchNearBlue:Permission.bluetoothScan,S.current.connectNearBlue:Permission.bluetoothConnect};
  handleBluePermission(BuildContext mContext,CallBack callBack)async{
    bool grandLocationBol = true;
    for(var element in locationPermissions.keys){
      if(await locationPermissions[element]?.status != PermissionStatus.granted){
        grandLocationBol = false;
      }
    }
    bool grandBlueBol = true;
    for(var element in bluePermissions.keys){
      if(await bluePermissions[element]?.status != PermissionStatus.granted){
        grandBlueBol = false;
      }
    }
    final locationService = await getLocationServiceCheck();

    if(grandLocationBol == false){
      if (mContext.mounted) {
        showPermissionRequestDialog(mContext, centralControlBol:true,onSuccess: () async {
          requestPermissions(mContext,{...locationPermissions,...bluePermissions},(bool success, String msg) async{
            if(success){
              //打开定位服务
              if (!locationService) {
                if (mContext.mounted) {
                  showPermissionDialog(mContext,callBack,centralControlBol:true);
                }
              }else{
                callBack(true,S.current.finishGrandPer);
              }
            }else{
              EasyLoading.showError(msg);
              callBack(false,msg);
            }
          });
        });
      }
    } else if(grandBlueBol == false){
      if(mContext.mounted){
        requestPermissions(mContext,bluePermissions,(bool success, String msg) async{
          if(success){
            //打开定位服务
            if (!locationService) {
              if (mContext.mounted) {
                showPermissionDialog(mContext,callBack,centralControlBol:true);
              }
            }else{
              callBack(true,S.current.finishGrandPer);
            }
          }else{
            EasyLoading.showError(msg);
            callBack(false,msg);
          }
        });
      }
    }else if(!locationService){
      if(mContext.mounted) {
        showPermissionDialog(mContext, callBack,centralControlBol:true);
      }
    }else{
      //都授权了
      callBack(true,S.current.finishGrandPer);
    }
  }

  ///["存储权限", "定位权限", "后台定位权限"]
  static final locationPermissions = {S.current.locationPermission:Permission.location,S.current.backLocationPermission:Permission.locationWhenInUse};
  static handleLocationPermission(BuildContext mContext,CallBack callBack) async{
    final location = await Permission.location.status;
    final locationWhenInUse = await Permission.locationWhenInUse.status;
    final locationService = await getLocationServiceCheck();//ios 不需要

    if (location != PermissionStatus.granted||locationWhenInUse != PermissionStatus.granted) {
      if (mContext.mounted) {
        showPermissionRequestDialog(mContext, onSuccess: () async {
          requestPermissions(mContext,locationPermissions,(bool success, String msg) async{
            if(success){
              //打开定位服务
              if (!locationService) {
                if (mContext.mounted) {
                  showPermissionDialog(mContext,callBack);
                }
              }else{
                callBack(true,S.current.finishGrandPer);
              }
            }else{
              EasyLoading.showError(msg);
            }
          });
        });
      }
    }else if(!locationService){
      if(mContext.mounted) {
        showPermissionDialog(mContext, callBack);
      }
    }else{
      //都授权了
      callBack(true,S.current.finishGrandPer);
    }
  }

  ///[permissions] {'存储权限':Permission.storage}
  static requestPermissions(BuildContext mContext,Map<String,Permission> permissions, CallBack callBack) async {
    final Map<Permission, PermissionStatus> statuses = {};
    for (var element in permissions.values) {
      statuses[element] = await element.request();
    }

    List deniedNames = [];
    List pDeniedNames = [];
    statuses.forEach((key, value) {
      if (value.isDenied) {
        deniedNames = _addNames(deniedNames, key,permissions);
      } else if (value.isPermanentlyDenied) {
        pDeniedNames = _addNames(pDeniedNames, key,permissions);
      }
    });
    if (deniedNames.isNotEmpty) {
      List list1 = _listContains(deniedNames, permissions.keys.toList());
      if (list1.isNotEmpty) {
        bool al = list1.contains(S.current.backLocationPermission);
        if(mContext.mounted){
          showDialog(
            context: mContext,
            barrierDismissible: false,
            builder: (BuildContext context) => StatefulBuilder(
              builder: (context, setState) {
                return MyDialog(
                  title: S.current.cancelPermission,
                  content: Text.rich(TextSpan(children: [
                    TextSpan(
                      text: "${S.current.cancelPermission}:${list1.join("、")}，${S.current.cancelPermissionTips2}${al ? " ${S.current.cancelPermissionTips3}”" : ""},${S.current.cancelPermissionTips4}",
                    ),
                    TextSpan(
                        text: '${S.current.setByHand}>>',
                        style: const TextStyle(color: Color(0xff0D83F6),decoration: TextDecoration.underline,),
                        recognizer: TapGestureRecognizer()
                          ..onTap = () async{
                            Navigator.of(context).pop();

                            Timer.periodic(const Duration(seconds: 1), (Timer t)async{
                              var hasAllPermissions = true;
                              for(var element in permissions.values){
                                if(await element.status != PermissionStatus.granted){
                                  hasAllPermissions = false;
                                  break;
                                }
                              }

                              if(hasAllPermissions){
                                if(mContext.mounted){
                                  requestPermissions(mContext,permissions,callBack);
                                }
                                t.cancel();
                              }
                            });

                            //无法监听到状态
                            openAppSettings();
                          })
                  ])),
                  cancelName: S.current.cancel,
                  confirmName: S.current.reOpen,
                  onCancel: () {
                    Navigator.of(context).pop();
                    callBack(false, S.current.cancelPermission);
                  },
                  onConfirm: () async {
                    Navigator.of(context).pop();
                    requestPermissions(mContext, permissions,callBack);
                  },
                );
              },
            ),
          );
        }
      }
    } else if (pDeniedNames.isNotEmpty) {
      List list1 = _listContains(pDeniedNames, permissions.keys.toList());
      if (list1.isNotEmpty) {
        bool al = list1.contains(S.current.backLocationPermission);
        if(mContext.mounted){
          showDialog(
            context: mContext,
            barrierDismissible: false,
            builder: (BuildContext context) => StatefulBuilder(
              builder: (context, setState) {
                return MyDialog(
                  title: S.current.rejectPermission,
                  content: Text("${S.current.rejectPermissionTips1}${list1.join("、")}，${S.current.rejectPermissionTips2}${al ? "，${S.current.rejectPermissionTips3}”" : ""}"),
                  cancelName: S.current.settLater,
                  confirmName: S.current.goSet,
                  onCancel: () {
                    Navigator.of(context).pop();
                    callBack(false, S.current.settLaterTips);
                  },
                  onConfirm: () async {
                    Navigator.of(context).pop();
                    Timer.periodic(const Duration(seconds: 1), (Timer t)async{
                      var hasAllPermissions = true;

                      for(var element in permissions.values){
                        if(await element.status != PermissionStatus.granted){
                          hasAllPermissions = false;
                          break;
                        }
                      }

                      if(hasAllPermissions){
                        if(mContext.mounted){
                          requestPermissions(mContext,permissions,callBack);
                        }
                        t.cancel();
                      }
                    });

                    //无法监听到状态
                    openAppSettings();
                  },
                );
              },
            ),
          );
        }
      }
    } else {
      callBack(true, S.current.finishGrandPer);
    }
  }

  static List _addNames(names, key,Map<String,Permission> mPermissions) {
    names.add(mPermissions.reverse()[key]);
    return names;
  }

  static List _listContains(List listA, List listC) {
    List listD = [];
    if (listA.isEmpty) return listD;
    for (var o in listC) {
      if (listA.contains(o)) listD.add(o);
    }
    return listD;
  }

  ///打开应用设置权限
  static openAppSetting() =>openAppSettings();
  ///判断定位服务是否打开（手机下拉菜单定位开关）
  static getLocationServiceCheck() async=> await Geolocator.isLocationServiceEnabled();

  ///弹窗提示是否进入 系统定位服务
  static showPermissionDialog(BuildContext mContext,CallBack callBack,{bool centralControlBol = false}) {
    showDialog(
      context: mContext,
      barrierDismissible: false,
      builder: (BuildContext context) => StatefulBuilder(
        builder: (context, setState) {
          return MyDialog(
            title: S.current.noLocationService,
            content: Text(S.current.unLocationPerTipsTo),
            cancelName: S.current.cancel,
            confirmName: S.current.setting,
            onCancel: () {
              Navigator.of(context).pop();
            },
            onConfirm: () async {
              Navigator.of(context).pop();

              Timer.periodic(const Duration(seconds: 1), (Timer t) async{
                final handlePermission = await getLocationServiceCheck();

                if(handlePermission){
                  if(mContext.mounted){
                    callBack(true,S.current.finishGrandPer);
                  }
                  t.cancel();
                }
              });
              Geolocator.openAppSettings();
            },
          );
        },
      ),
    );
  }

  ///弹窗提示授予定位权限
  static showPermissionRequestDialog(BuildContext context,
      {required Function onSuccess,bool centralControlBol = false}) {
    showDialog(
      context: context,
      barrierDismissible: false,
      builder: (BuildContext context) => StatefulBuilder(
        builder: (context, setState) {
          return MyDialog(
            title: S.current.unLocationPer,
            content: Text(S.current.unLocationPerTips),
            cancelName: S.current.cancel,
            confirmName: S.current.openLocation,
            onCancel: () {
              Navigator.of(context).pop();
            },
            onConfirm: () async {
              Navigator.of(context).pop();
              onSuccess();
            },
          );
        },
      ),
    );
  }

  ///弹窗提示授予相机
  static showCameraPermissionDialog(BuildContext context,
      {required Function onSuccess,bool centralControlBol = false}) {
    if(Platform.isIOS){
      onSuccess();
      return;
    }
    showDialog(
      context: context,
      barrierDismissible: false,
      builder: (BuildContext context) => StatefulBuilder(
        builder: (context, setState) {
          return MyDialog(
            title: S.current.dialogTitle2,
            content: Column(
              mainAxisSize: MainAxisSize.min,
              children: [
                Text(S.current.dialogContent),
              ],
            ),
            cancelName: S.current.cancel,
            confirmName: S.current.confirm,
            onCancel: () {
              Navigator.of(context).pop();
            },
            onConfirm: () async {
              Navigator.of(context).pop();
              onSuccess();
            },
          );
        },
      ),
    );
  }


}